/*
 * File Name：DownLoad.java
 * Copyright：Copyright 2008-2014 CiWong.Inc. All Rights Reserved.
 * Description： DownLoad.java
 * Modify By：res-jianpingliu
 * Modify Date：2014-4-7
 * Modify Type：Add
 */
package com.ciwong.epaper.modules.reciteWords.util.download;

import android.content.Context;
import android.text.TextUtils;
import android.util.Log;

import com.ciwong.epaper.application.EpaperConstant;
import com.ciwong.epaper.event.EventBusFactory;
import com.ciwong.epaper.util.DialogUtil;
import com.ciwong.epaper.util.ESystem;
import com.ciwong.epaper.util.FeedbackUtil;
import com.ciwong.epaper.util.FileUtil;
import com.ciwong.epaper.util.download.DownLoadDB;
import com.ciwong.epaper.util.download.DownLoadInfo;
import com.ciwong.epaper.util.download.DownloadStatus;
import com.ciwong.eventbus.EventBus;
import com.ciwong.libs.utils.CWLog;
import com.ciwong.libs.utils.FileUtils;
import com.ciwong.mobilelib.i.BaseCallBack;
import com.ciwong.mobilelib.utils.ThreadTask;
import com.ciwong.mobilelib.utils.ZipHelper;
import com.liulishuo.filedownloader.BaseDownloadTask;
import com.liulishuo.filedownloader.FileDownloadListener;
import com.liulishuo.filedownloader.FileDownloader;

import java.io.File;
import java.util.ConcurrentModificationException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

;

/**
 * 文件下载工具类
 * <p>
 * 如果是apk文件下载，需要调用一下setContext方法(最重要的是要保证数据库，界面显示层中，还有控制器中三者对象数据的一致性)
 *
 * @author res-jianpingliu
 * @version ciwong v.1.0 2014-4-7
 * @since ciwong v.1.0
 */
  public class BaseDownLoad {
    private static final String TAG = "BaseDownLoad";


    /**
     * 默认保存路径(解压文件)
     */
//    public static final String DEFUALT_PACKAGE_DIR = ESystem.getReciteWordBookPath();


    private Map<String, BaseDownloadTask> taskSparseArray = new HashMap<>();

    private static BaseDownLoad instance;

    private List<DownLoadInfo> mUnCompletedTastList;
    private static Context mContext;
    /**
     * 私有construction
     */
    private BaseDownLoad() {
        setUncompleteTaskList();
    }

    /**
     * 获得AppDownService单例
     *
     * @return AppDownService单例
     */
    public static BaseDownLoad getInstance() {
        if (instance == null) {
            syncInit();
        }
        return instance;
    }

    /**
     * 实例化对象
     */
    private static synchronized void syncInit() {
        if (instance == null) {
            instance = new BaseDownLoad();
        }
    }
    /**
     * 设置上下文对象
     *
     * @param context 上下文对象
     */
    public static void setContext(Context context) {
        mContext = context;
    }

    /**
     * 添加一个下载任务
     *
     * @param bean 下载地址
     */
    public void addTask(final DownLoadInfo bean) {

        try {
            DownLoadInfo tempbean = getCurrentBean(bean);
            // 如果是新添加任务则使用原对象，否则获取当前list中的对象
            if (tempbean == null) {
                tempbean = bean;
            }
            if (tempbean == null || TextUtils.isEmpty(tempbean.getUrl())) {
                return;
            }
            if (TextUtils.isEmpty(tempbean.getSavePath())) {
                tempbean.setSavePath(
                        FileUtil.getSavePathByUrl(mContext, tempbean.getUrl()));
            }

            // 如果解压后的目录存在则直接返回下载成功
            if (tempbean.getStatus() == 5 || !mUnCompletedTastList.contains(tempbean)) {
                mUnCompletedTastList.add(tempbean);
            }

            startFileDownload(tempbean);
            insertDetailToDB(tempbean);
            EventBus.getDownLoadInstance().post(
                    new EventBusFactory.DownloadEvent(tempbean, null));
            Log.e(TAG, "addTask:tempBean.getStatus()== " + tempbean.getStatus());
        } catch (Exception e) {
            e.getStackTrace();
        }
    }

    private void startUpZip(DownLoadInfo bean) {
        CWLog.i("se7en", "STATU_UPZIPING");
        DownLoadInfo b = getCurrentBean(bean);
        if (b == null) {
            b = bean;
        }
        final DownLoadInfo tempbean = b;
        if (tempbean == null) {
            return;
        }
        Log.d("xixin", "-------------点击18---解压了");
        tempbean.setStatus(DownloadStatus.STATUS_UPZIPING);
        insertDetailToDB(tempbean);
        EventBus.getDownLoadInstance()
                .post(new EventBusFactory.DownloadEvent(tempbean, null));
        Log.d("upzip", "##########DownLoad startUpZip##########");
        String DEFUALT_PACKAGE_DIR = ESystem.getReciteWordBookPath();
        ZipHelper.getInstance().addToUpZipTask(tempbean.getSavePath(),
                DEFUALT_PACKAGE_DIR, new BaseCallBack() {
                    @Override
                    public void success(Object data) {

                        CWLog.e(TAG, "##########upzip success##########");
                        tempbean.setStatus(DownloadStatus.STATUS_COMPLETED);
                        if (tempbean != null) {
                            Log.e("MyWorkFragment", "success: 解压成功" + tempbean.getModuleId());
                        }

                        mUnCompletedTastList.remove(tempbean);
                        // 更新下载状态
                        insertDetailToDB(tempbean);
                        CWLog.e("xixin", "-------------点击19---成功了" + tempbean.getStatus());
                        EventBus.getDownLoadInstance().post(
                                new EventBusFactory.DownloadEvent(tempbean,
                                        null));
                    }

                    @Override
                    public void failed(Object data) {
                        Log.d("upzip", "##########DownLoad failed##########");
                        if (tempbean.getSavePath() != null)
                            deleteReciteWordBookFile(tempbean.getSavePath());
                        // 更新下载状态
                        tempbean.setStatus(DownloadStatus.STATUS_FAILED);
                        insertDetailToDB(tempbean);
                        Log.e("xixin", "-------------点击20---解压失败了" + tempbean.getStatus());
                        EventBus.getDownLoadInstance().post(
                                new EventBusFactory.DownloadEvent(tempbean,
                                        null));
                    }

                    @Override
                    public void failed(int errorCode, Object data) {
                        failed(data);
                    }
                });

    }

    public void pauseTask(DownLoadInfo bean) {
        DownLoadInfo tempBean = getCurrentBean(bean);
        if (tempBean == null) {
            tempBean = bean;
            mUnCompletedTastList.add(tempBean);
        }
        tempBean.setStatus(DownloadStatus.STATUS_PAUSE);
        insertDetailToDB(tempBean);
        Log.i("lqi", "----------------------pauseTask-----------ChapterId: ----------" + tempBean.getChapterId());
        BaseDownloadTask task;

        task = taskSparseArray.get(tempBean.getBookId());
        if (task == null) {
            return;
        }
        FileDownloader.getImpl().pause(task.getId());
        EventBus.getDownLoadInstance()
                .post(new EventBusFactory.DownloadEvent(tempBean, null));
        Log.e("MyWorkFragment", "pauseTask:tempBean.getStatus()== " + tempBean.getStatus());
    }

    public void resumeTask(DownLoadInfo bean) {
        CWLog.i("se7en", "resumeTask");
        Log.d("xixin", "-----------暂停状态--------");
        DownLoadInfo tempBean = getCurrentBean(bean);
        if (tempBean == null) {
            tempBean = bean;
            mUnCompletedTastList.add(tempBean);
        }
        tempBean.setStatus(DownloadStatus.STATUS_DOWNLOADING);
        Log.d("xixin", "-----------暂停状态改变状态--------" + tempBean.getStatus());
        insertDetailToDB(tempBean);
        startFileDownload(tempBean);
        Log.e("MyWorkFragment", "resumeTask:tempBean.getStatus()== " + tempBean.getStatus());
        EventBus.getDownLoadInstance()
                .post(new EventBusFactory.DownloadEvent(tempBean, null));
    }


   /* *//**
     * 停止任务
     *
     *//*
    public void stopTask(final DownLoadInfo bean) {
        CWLog.i("se7en", "stopTask");
        DownLoadInfo tempBean = getCurrentBean(bean);
        if (tempBean == null) {
            tempBean = bean;
        }
        // download.stop(tempBean.getSavePath());
        BaseDownloadTask task;
        task = taskSparseArray.get(tempBean.getBookId());

        if (task == null) {
            return;
        }
        FileDownloader.getImpl().pause(task.getId());
        // 如果该任务也是未完成任务，那么从未完成列表中移除
        if (mUnCompletedTastList.contains(tempBean)) {
            mUnCompletedTastList.remove(tempBean);
        }
        Log.d("xixin", "-------------点击21---下载状态变成0");
        tempBean.setStatus(DownloadStatus.STATUS_NORMAL);
        insertDetailToDB(tempBean);
        EventBus.getDownLoadInstance()
                .post(new EventBusFactory.DownloadEvent(tempBean, null));
    }

    public void stopTaskList() {
        for (int i = 0; i < mUnCompletedTastList.size(); i++) {
            DownLoadInfo info = mUnCompletedTastList.get(i);
            if (info.getStatus() == DownloadStatus.STATUS_LOADING
                    || info.getStatus() == DownloadStatus.STATUS_DOWNLOADING) {
                Log.d("xixin", "-------------点击24---stopTaskList");
                stopTask(info);
            }
        }
    }
*/
    public DownLoadInfo getCurrentBean(DownLoadInfo info) {
        DownLoadInfo currentBean = null;
        int indexOf = mUnCompletedTastList.indexOf(info);
        if (indexOf != -1) {
            currentBean = mUnCompletedTastList.get(indexOf);
        }
        return currentBean;
    }


    /**
     * 继续所有未完成任务
     */
    public void resumeUnCompletedList() {
        try {
            for (DownLoadInfo bean : mUnCompletedTastList) {
                switch (bean.getStatus()) {
                    case DownloadStatus.STATUS_FAILED:
                        addTask(bean);
                        break;
                    case DownloadStatus.STATUS_NORMAL:
                    case DownloadStatus.STATUS_LOADING:
                    case DownloadStatus.STATUS_DOWNLOADING:
                    case DownloadStatus.STATUS_PAUSE:
                        resumeTask(bean);
                        break;
                    case DownloadStatus.STATUS_UPZIPING:
                        startUpZip(bean);
                        break;
                }
            }
        } catch (ConcurrentModificationException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获得所有未完成的任务列表
     *
     * @return 未完成的任务列表
     */
    private void setUncompleteTaskList() {
        mUnCompletedTastList = DownLoadDB.queryUnCompletedList();
        if (mUnCompletedTastList.size() > 0) {
            resumeUnCompletedList();
        }

    }

    private void insertDetailToDB(final DownLoadInfo bean) {
        ThreadTask.getInstance().executorDBThread(new Runnable() {
            public void run() {
                DownLoadDB.insertDetail(bean);
            }
        }, ThreadTask.ThreadPeriod.PERIOD_HIGHT);
    }

    /**
     * 删除解压后，被添加到数据库后的文件
     *
     * @param savePath
     */
    public void deleteReciteWordBookFile(String savePath) {
        Log.d("xixin", "-------------点击23---deleteReciteWordBookFile");
        try {
            FileUtils.delete(getUpZipFilePath(savePath));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private String getUpZipFilePath(String savePath){
        String fileName = savePath.substring(savePath.lastIndexOf("/"));
        String packageDir = ESystem.getPackagesReciteWord(fileName.substring(0,fileName.indexOf(".")));
        return packageDir;
    }

    public void deleteTask(DownLoadInfo downLoadInfo) {
        String packageDir = ESystem.getPackagesCatalogue(
                downLoadInfo.getBookId(), downLoadInfo.getChapterId());
        FileUtils.delete(packageDir);
        downLoadInfo.setStatus(DownloadStatus.STATUS_FAILED);
        insertDetailToDB(downLoadInfo);
        EventBus.getDownLoadInstance().post(
                new EventBusFactory.DownloadEvent(downLoadInfo,
                        null));
    }

    FileDownloadListener mFileDownloadListener = new FileDownloadListener() {
        @Override
        protected void pending(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            DownLoadInfo downLoadInfo = (DownLoadInfo) task.getTag();
            downLoadInfo.setStatus(DownloadStatus.STATUS_LOADING);
            Log.i("lqi", "---pending: ");
            insertDetailToDB(downLoadInfo);
            EventBus.getDownLoadInstance().post(
                    new EventBusFactory.DownloadEvent(downLoadInfo,
                            null));

        }

        @Override
        protected void connected(BaseDownloadTask task, String etag, boolean isContinue, int soFarBytes, int totalBytes) {
            Log.i("lqi", "-connected--total: " + totalBytes);
            DownLoadInfo downLoadInfo = (DownLoadInfo) task.getTag();
            if (downLoadInfo == null) {
                return;
            }
            downLoadInfo.setLength(totalBytes);
            insertDetailToDB(downLoadInfo);
        }

        @Override
        protected void progress(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            if (soFarBytes == 0) {
                return;
            }
            DownLoadInfo downLoadInfo = (DownLoadInfo) task.getTag();
            float progress = soFarBytes / (float) totalBytes;
            downLoadInfo.setProgress((int) (progress * 100));
            downLoadInfo.setStatus(DownloadStatus.STATUS_DOWNLOADING);
            System.out.println("lqi -progress: " + progress);
            EventBus.getDownLoadInstance().post(
                    new EventBusFactory.DownloadEvent(downLoadInfo, null));
        }

        @Override
        protected void completed(BaseDownloadTask task) {
            Log.i("lqi", "---completed: ");
            DownLoadInfo downLoadInfo = (DownLoadInfo) task.getTag();
            if (DialogUtil.sdIsFullForDownload(mContext, downLoadInfo)) {
                deleteTask(downLoadInfo);
            } else {
                startUpZip(downLoadInfo);
            }
            String logDesc = "";
            if (null != task) {
                logDesc = "errorCode" + task + "##############" + task.getUrl();
            }

            taskSparseArray.remove(downLoadInfo.getBookId());

            downLoadInfo.setStatus(DownloadStatus.STATUS_FILE_DOWNLOAD);
            EventBus.getDownLoadInstance()
                    .post(new EventBusFactory.DownloadEvent(downLoadInfo, null));
            CWLog.e(TAG, "completed:下载成功:0 " + logDesc);
        }

        @Override
        protected void paused(BaseDownloadTask task, int soFarBytes, int totalBytes) {
            Log.i("lqi", "---paused: ");
            DownLoadInfo downLoadInfo = (DownLoadInfo) task.getTag();
            downLoadInfo.setStatus(DownloadStatus.STATUS_PAUSE);
            insertDetailToDB(downLoadInfo);
            taskSparseArray.remove(downLoadInfo.getBookId());

            EventBus.getDownLoadInstance()
                    .post(new EventBusFactory.DownloadEvent(downLoadInfo, null));
        }

        @Override
        protected void error(BaseDownloadTask task, Throwable e) {
            Log.i("lqi", "---error: ");
            String logDesc = "";
            if (null != task) {
                logDesc = "errorCode" + task + "##############" + task.getUrl();
            }
            FeedbackUtil.getInstance().addFeedbackLog(FeedbackUtil.FEEDBACK_TYPE_DOWNLOAD_RES, logDesc, EpaperConstant.DOWNLOAD_STATE_FAIL);
            DownLoadInfo downLoadInfo = (DownLoadInfo) task.getTag();
            File file = new File(downLoadInfo.getSavePath());
            if (file.exists()) {
                file.delete();
            }
            // 更新下载状态
            downLoadInfo.setStatus(DownloadStatus.STATUS_FAILED);
            CWLog.e(TAG, "下载失败: " + logDesc + "   " + e.getMessage());
            insertDetailToDB(downLoadInfo);
            EventBus.getDownLoadInstance().post(
                    new EventBusFactory.DownloadEvent(downLoadInfo,
                            null));
        }

        @Override
        protected void warn(BaseDownloadTask task) {
            Log.i("lqi", "---warn: ");
        }
    };


    private void startFileDownload(DownLoadInfo downLoadInfo) {
        FileDownloader mFileDownloader = FileDownloader.getImpl();
        mFileDownloader.setMaxNetworkThreadCount(1);

        BaseDownloadTask task = mFileDownloader.create(downLoadInfo.getUrl())
                .setPath(downLoadInfo.getSavePath())
                .setAutoRetryTimes(15)
                .setTag(downLoadInfo)
                .setListener(mFileDownloadListener);

        taskSparseArray.put(downLoadInfo.getBookId(), task);

        task.start();

    }



}